import 'dart:async';

import 'package:automated_test/common/device_order.dart';
import 'package:automated_test/model/device_env.dart';
import 'package:automated_test/model/device_info.dart';
import 'package:dio/dio.dart';
import 'myLog.dart';

///处理网络请求
class Network {
  ///三方平台测试服闸机接口地址
  // static final String baseUrl = "http://47.107.108.76:9101/u1/v1/gex2";

  ///运维云闸机调试接口
  static final String baseUrl = "https://op.cytingchechang.com";

  ///三方请求参数secretKey的值
  static final String secretKey = "9018C282A02345C9AB95E3E2D4EE3ED4";

  static final Dio mDio = Dio();

  ///用于Dio初始化
  ///插件文档 https://pub.flutter-io.cn/packages/dio
  static void init() {
    mDio.options.baseUrl = baseUrl;
    mDio.options.headers = {
      // "secretKey": secretKey,
      "Content-Type": "application/json"
    };

    ///连接超时时间 单位：毫秒
    mDio.options.connectTimeout = 3000;
  }

  ///获取设备tokenId,用于查询主板状态
  static Future<int?> getDeviceTokenId(String mac) async {
    var deviceInfo = DeviceInfo.fromJson(await getDeviceInfo(mac));
    return deviceInfo.data?.rows?[0].tokenId;
  }

  ///返回响应请求结果的Map
  ///
  ///该方法用于查询主板状态
  ///
  ///[mac]主板mac地址
  ///
  /// 响应参数
  /// 参数名                类型         描述
  /// code                 Integer     状态码1表示成功，其他异常
  /// message              String      状态描述
  /// data                 Object      响应体数据
  /// motherboardStatus    String      主板状态
  /// infraredState        String      红外状态，00000000 为正常
  /// motorStatus          String      电机状态
  /// limitStatus          String      限位状态
  /// https://op.cytingchechang.com/internal/public/deviceTrace?departmentId=2&mac=BC:FF:4D:34:28:4D
  static Future<Map<String, dynamic>> getDeviceStatus(String mac) async {
    var tokenId = await getDeviceTokenId(mac);
    if (tokenId == null) {
      return {};
    }
    Response response = await mDio
        .get('/v1/gex2Operational/getImportantParameter', queryParameters: {
      "id": tokenId
    }).catchError((error) => handleError(error));
    Map<String, dynamic> data = response.data;
    MyLog.i("getDeviceStatus", "$data");
    return data;
  }

  ///该方法用于查询设备信息
  ///
  /// [mac]主板Mac
  ///
  ///响应参数
  /// 参数名          类型        描述
  /// code           Integer     1：成功；-1：请求失败
  /// message        String      响应信息
  /// data           Object      数据
  /// mac            String      设备mac
  /// status         Integer     是否在线: 0-掉线；1-在线
  /// loginAt        Long        登录时间戳
  static Future<Map<String, dynamic>> getDeviceInfo(String mac) async {
    Response response = await mDio.get("/internal/deviceTrace",
        queryParameters: {
          "departmentId": "2",
          "mac": mac
        }).catchError((error) => handleError(error));
    Map<String, dynamic> data = response.data;
    MyLog.i("getDeviceInfo", "$data  ${data is Map}");
    return data;
  }

  ///返回响应结果Map
  ///
  ///该方法用于风扇调试
  ///
  /// [mac]主板mac [type] 1开，0关
  ///
  /// 响应参数
  /// 参数名     类型        描述
  /// code       Integer     1：成功；-1：请求失败
  /// message    String      响应信息
  ///
  static Future<Map<String, dynamic>> fanDebug(String mac, int type) async {
    Response response = await mDio
        .get("/v1/fanControlRest/openOrCloseFanControl/$mac/$type")
        .catchError((error) => handleError(error));

    Map<String, dynamic> data = response.data;
    MyLog.i("fanDebug", "$data  ${data is Map}");
    return data;
  }

  ///该方法用于设备调试
  ///[order] 指令介绍
  /// order = G1：左开闸
  /// order = G2：右开闸
  /// order = G3：左开闸（镜像模式、反向开闸），相当于右开闸
  /// order = G4：右开闸（镜像模式、反向开闸），相当于左开闸
  /// order = G5：左常开开闸
  /// order = G6：左常开关闸
  /// order = G7：右常开开闸
  /// order = G8：右常开关闸
  /// order = G9：出向延时时间
  /// [value]：数值以秒为单位，值范围 1~100
  ///
  /// order = G10：左边通行语音
  /// value值代表的语音内容见通行语音文档 https://easydoc.net/s/89481110/etA5il2W/4jHATQPc
  ///
  /// order = G11：右边通行语音
  /// value值代表的语音内容见通行语音文档
  ///
  /// order = G12：开关门速度设置
  /// value：值范围 1~10
  ///
  /// order = G13：断电开闸方向
  /// value：0-入口开；1-出口开
  /// order = G14：语音音量
  /// value：值范围 1~15
  ///
  /// 返回响应结果Map
  /// 响应参数  application/json
  /// 参数名     类型      描述
  /// code      Integer   1：成功；-1：请求失败
  /// message    String    响应信息
  /// e.g. https://op.cytingchechang.com/internal/public/deviceTrace?departmentId=2&mac=BC:FF:4D:34:28:4D
  static Future<Map<String, dynamic>> deviceDebug(String mac, String order,
      [int? value]) async {
    Response response;
    if (value == null) {
      response = await mDio.post("/v1/gex2Operational/setParameter", data: {
        "mac": mac,
        "data": [
          {"order": DeviceOrderUtils.getOrderOf(order)}
        ]
      }).catchError((error) => handleError(error));
    } else {
      response = await mDio.post("/v1/gex2Operational/setParameter", data: {
        "mac": mac,
        "data": [
          {"order": DeviceOrderUtils.getOrderOf(order), "value": value}
        ]
      }).catchError((error) => handleError(error));
    }
    Map<String, dynamic> data = response.data;
    MyLog.i("deviceDebug", "$data");
    return data;
  }

  ///该方法读取闸机参数值
  ///
  /// order = G9：出向延时时间
  /// order = G10：左边通行语音
  /// value值代表的语音内容见通行语音文档
  /// order = G11：右边通行语音
  /// value值代表的语音内容见通行语音文档 https://easydoc.net/s/89481110/etA5il2W/4jHATQPc
  /// order = G12：开关门速度设置
  /// order = G13：断电开闸方向
  /// order = G14：语音音量
  ///
  /// 响应参数
  /// 参数名    类型      描述
  /// code     Integer   状态码1表示成功，其他异常
  /// message  String    状态描述
  /// data     Object    响应数据
  /// mac      String    设备mac
  /// value    String    设置的值
  /// updateAt Long      更新时间戳
  static Future<Map<String, dynamic>> readParam(
      String mac, String order) async {
    var tokenId = await getDeviceTokenId(mac);
    if (tokenId == null) {
      return {};
    }
    Response response = await mDio
        .get(
            "/v1/gex2Operational/getParameterActual/${DeviceOrderUtils.readOrderOf(order)}/$tokenId")
        .catchError((error) => handleError(error));

    Map<String, dynamic> data = response.data;
    MyLog.i("readParam", "$data");
    return data;
  }

  ///获取设备温湿度
  static Future<DeviceEnv> getEnv(String mac) async {
    Response response = await mDio.get("/v1/device/fan/real/$mac");
    var deviceEnv = DeviceEnv.fromJson(response.data);
    MyLog.d("getEnv", deviceEnv.toJson().toString());
    return deviceEnv;
  }

  ///该方法用于查重 TODO:接口还未上云服务器
  ///
  /// 相应参数
  /// 参数名    类型        描述
  /// code     Integer    状态码1表示成功，其他异常
  /// message  String     状态描述
  static Future<Map<String, dynamic>> checkDuplicate(String mac) async {
    Response response = await mDio.get("http://192.168.0.204:9200/check",
        queryParameters: {
          "mac": "$mac"
        }).catchError((error) => handleError(error),
        test: (object) => test(object));
    Map<String, dynamic> data = response.data;
    MyLog.i("checkDuplicate", "url: http://192.168.0.204:9200/check?mac=$mac\n data: $data");
    return data;
  }

  ///用于处理网络请求产生的异常
  ///[error]异常对象
  ///返回响应的对象
  static Future<Response> handleError(Exception error) {
    MyLog.e("handleError", "$error");
    error = error as DioError;
    String message;
    switch (error.type) {
      case DioErrorType.connectTimeout:
        message = "服务器响应超时";
        break;
      case DioErrorType.other:
        message = error.message;
        break;
      default:
        // message = error.message;|
        message = "抱歉，出错了";
    }
    Response response = Response(
        requestOptions: RequestOptions(path: ""),
        data: {"code": -1, "message": message});
    return Future(() => response);
  }

  static bool test(Object object) {
    MyLog.w("test", "$object");
    return true;
  }
}
